/* Pically
 * Copyright (C) 2011 Petros Dolaschjan.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package de.pd.pically.util;

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

import de.pd.pically.bean.CalendarEventBean;
import de.pd.pically.bean.CalendarEventBean.EventType;
import de.pd.pically.bean.CalendarEventContainer;

/**
 * @author petros
 *
 */
public class CalCreator {

	public void createPdf(String[] pImgs, int pYear, CalendarEventContainer pEvtCont, String pTargetFile) throws Exception {

		System.out.println("Creating calendar for year " + pYear);
		// step 1: creation of a document-object
		Document document = new Document(PageSize.A4, 30, 30, 50, 10);  // TODO: configurable

			PdfWriter.getInstance(document, new FileOutputStream(pTargetFile)); // TODO: param

			// step 3: we open the document
			document.open();

			// Fonts
			String uri = CalCreator.class.getResource("/de/pd/pically/resources/Arial.ttf").toURI().toString();
			
			BaseFont bfComic = BaseFont.createFont(
					uri, BaseFont.CP1252,
					BaseFont.NOT_EMBEDDED);
			Font font = new Font(bfComic, 18);  // TODO: configurable

			Font fontSmall = new Font(bfComic, 8); // TODO: configurable
			fontSmall.setColor(new Color(70, 70, 70));

			Font fontSmallRed = new Font(bfComic, 8); // TODO: configurable
			fontSmallRed.setColor(Color.RED);
			
			Font birthdayFont = new Font(bfComic, 8); // TODO: configurable
			birthdayFont.setColor(Color.BLUE);

			Font fontSmallWeek = new Font(bfComic, 10); // TODO: configurable
			fontSmallWeek.setStyle(Font.BOLD);
			
			Color colDarkGrey = new Color(222, 222, 222);
			Color colBroder = new Color(202, 202, 202);
			
			// ------------

			//document.add(new Paragraph("Calendar " + pYear));

			//document.newPage();
			
			
			
			// Iterate the months 

			for (int month = 0; month < 12; month++) {

				Calendar cal = new GregorianCalendar(pYear, month, 1);

				File imgFile = (pImgs[month] != null) ? new File(pImgs[month]) : null;
				if(imgFile != null && imgFile.exists()) {
					Image image = Image.getInstance(pImgs[month]);
					image.setAlignment(Element.ALIGN_CENTER);
					image.scaleToFit(500, 375);
					document.add(image);
				}

				Paragraph title = new Paragraph(Utils.getMonthName(month) +  " " + pYear, font);
				title.setAlignment(Element.ALIGN_CENTER);

				document.add(title);

				document.add(new Paragraph(" "));

				PdfPTable table = new PdfPTable(7);

				/** Weekdays */
				int startDay = Calendar.MONDAY;
				Calendar gcal = new GregorianCalendar();
				gcal.setTime(new Date());
				gcal.set(Calendar.DAY_OF_WEEK, startDay);
				for(int nn = 0; nn < 7; nn++) {
					PdfPCell  dayOfWeekTitle = new PdfPCell(
							new Paragraph(Utils.getDayOfWeekkName(gcal.get(Calendar.DAY_OF_WEEK)), fontSmallWeek));
					dayOfWeekTitle.setHorizontalAlignment(Element.ALIGN_CENTER);
					dayOfWeekTitle.setBackgroundColor(colDarkGrey);
					dayOfWeekTitle.setBorderColor(colBroder);
					table.addCell(dayOfWeekTitle);
					gcal.add(Calendar.DAY_OF_WEEK, 1);
				}
				
				/** ============================== */

				int firstDay = cal.get(Calendar.DAY_OF_WEEK);

				if (firstDay == Calendar.SUNDAY) {
					firstDay = 7;
				} else {
					firstDay--;
				}

				boolean begin = false;
				boolean end = false;

				int dayOfWeek = 1;

				int dayCounter = 1;

				PdfPCell dayCell = null;

				
				// Iterate the days
				
				for (int day = 1; day <= 42; day++) {

					// when day first day begins
					if (dayOfWeek == firstDay && !begin) {
						begin = true;
					}

					// if not began, then emtpy boxes
					if (!begin || end) {
						dayCell = new PdfPCell(new Paragraph(" "));
						dayCell.setBackgroundColor(new Color(248, 248, 248)); // TODO: configurable
					// show the day
					} else {
						
						/*String event = "";
						
						boolean holiday = Pattern.matches(".*\\[HL\\].*", event);
						boolean birthday = Pattern.matches(".*\\[BT\\].*", event);
						
						event = event.replaceAll(" \\[..\\]", "");
						
						

						Font dayFont = fontSmall;
						if (holiday || birthday) {
							dayFont = fontSmallRed;
							
							if(birthday) {
								dayFont = birthdayFont;
							}
						}
						*/
						Font dayFont = fontSmall;
						ArrayList<CalendarEventBean> events = pEvtCont.getEvent(dayCounter, month+1);
						StringBuffer evtTitle = new StringBuffer();
						boolean containsHoliday = false;
						Image bdIcon = null;
						if(events != null) {
							int cnt = 1;
							for (CalendarEventBean event : events) {
								if(event.getEventType() == EventType.EVENT_BIRTHDAY) {
									try {
										String sIcon = CalCreator.class.getResource("/de/pd/pically/resources/ic_bday.png").toURI().toString();
										//System.out.println("adding icon " + sIcon);
										bdIcon = Image.getInstance(sIcon);
										bdIcon.setAlignment(Element.ALIGN_LEFT);
									} catch (URISyntaxException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
									
								}
								
								evtTitle.append(event.getText());
								if(cnt != events.size()) evtTitle.append(" - ");
								cnt++;
								if(event.getEventType() == EventType.EVENT_HOLIDAY) {
									containsHoliday = true;
								}
							}
						}

						dayCell = new PdfPCell(new Paragraph());
						Paragraph pp = new Paragraph("" + dayCounter
								+ " " + evtTitle.toString(), dayFont);
						dayCell.addElement(pp);

						if (dayOfWeek > 5 || containsHoliday) {
							dayCell
									.setBackgroundColor(new Color(248, 233, 233)); // TODO: configurable
						}

						dayCounter++;
					}
					
					dayCell.setBorderColor(colBroder);
					dayCell.setFixedHeight(50f);

					if (!end && dayCounter > cal
							.getActualMaximum(Calendar.DAY_OF_MONTH)) {
						end = true;
					}

					dayOfWeek++;

					if (dayOfWeek > 7) {
						dayOfWeek = 1;
					}

					table.getDefaultCell().setVerticalAlignment(
							Element.ALIGN_TOP);
					table.addCell(dayCell);

				}

				table.setWidthPercentage(95);
				// table.setTotalWidth(800);

				document.add(table);

				document.add(new Paragraph(" ", fontSmall));
				Paragraph footer = new Paragraph("Created with Pically: www.petrosit.de", fontSmall);
				footer.setAlignment(Element.ALIGN_RIGHT);
				document.add(footer);

				document.newPage();
			}

			document.newPage();

		

		// step 5: we close the document
		document.close();

		System.out.println("Done");

	}
}
